package com.license.logic.geneticAlgorithm.common;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.license.common.util.Constants;
import com.license.common.util.Utils;
import com.license.logic.alimentation.Alimentation;
import com.license.logic.alimentation.Food;
import com.license.logic.alimentation.FoodCharacteristics;
import com.license.logic.behaviorlog.RiskCalculation;
import com.license.logic.behaviorlog.RiskFactor;
import com.license.logic.jess.JessRecomandation;
import com.license.logic.preference.Activity;

public class CommonOperation{
	protected Random randomGenerator = new Random();
	protected Utils utils = new Utils();
	private Map<String ,Double> difference = new HashMap<String , Double>();
	public double lambda[] = new double[2];
	
	protected List<Activity> preferencedActivities;
	protected Map<String, Set<String>> exceptedFoods;
//	private JessRecomandation jessRecomandation = new JessRecomandation();
	protected Map<String, List<Food>> preferencedFoods;
	protected Map<String, List<Food>> allFoods;
	protected Document doc;
	private List<Food> exclusiveAllFoods = new ArrayList<Food>();
	private double gainedWeightPerWeek = 0;
	
	protected double desireKalory;
	protected double desireSbp;
	private static int numarApel = 0;
	private JessRecomandation jessRecomandation = new JessRecomandation();
	private static String diesease = "";
	private static int nr = 0;
	

	public CommonOperation(){
		lambda[0] = utils.generateRandomDouble(0, 1);
		lambda[1] = 1 - lambda[0];
		
	}
	
	public List<Activity> getPreferencedActivities() {
		return preferencedActivities;
	}

	public void setPreferencedActivities(List<Activity> preferencedActivities) {
		this.preferencedActivities = preferencedActivities;
	}

	public Map<String, List<Food>> getPreferencedFoods() {
		return preferencedFoods;
	}

	public void setPreferencedFoods(Map<String, List<Food>> preferencedFoods) {
		this.preferencedFoods = preferencedFoods;
	}
	
	public List<Activity> getNewSubstractActivity(List<Activity> activities1, List<Activity> activities2, double weight){
		List<Activity> newActivities = new ArrayList<Activity>();
		boolean found = true;
		for( Activity activity1 : activities1) {
			for( Activity activity2 : activities2) {
				Activity newActivity = new Activity();
				if(activity1.getName().equalsIgnoreCase(activity2.getName())) {
					found = true;
					if (activity1.getMinutes() == activity2.getMinutes()){
						newActivity = this.getRandomActivityCopy(this.preferencedActivities);
						newActivity.setKg(weight);
						newActivity.setMinutes(utils.generateRandomInt(Constants.MINIM_VALUE_ACTIVITY_DURATION, Constants.MAXIM_VALUE_ACTIVITY_DURATION));
					} else {
						newActivity = this.copyActivity(activity1);
						newActivity.setMinutes(Math.abs(activity1.getMinutes() - activity2.getMinutes()));
					}
					newActivities.add(newActivity);
					break;
				}
			}
			if (!found){
				newActivities.add(this.copyActivity(activity1));
			}
		}	
		return newActivities;
	}
	
	public Activity getRandomActivityCopy(List<Activity> activities){
		int index = activities.size() - 1;
		Activity activity = new Activity();
		if(index < 0 && activities.get(0)!=null) {
			index = 0 ;
			activity = activities.get(index);
		} else if(activities.get(index)!=null) {
			activity = activities.get(index);
		}
		return activity;
	}
	
	public Food getRandomFoodCopy(List<Food> foods, List<Food> allFoodsPerMeal,String mealType){
		String constraintMethod = Constants.JESS_CONSTRAINT_METHOD;
		Food newFood = null;
		boolean found;
		System.out.println("###################### " + numarApel + "  #######################");
		long startTime = System.currentTimeMillis();
		found = false;
		 while(!found) {
			if (allFoods.get(mealType).size() > 1) {
				newFood = allFoods.get(mealType).get(this.randomGenerator.nextInt(allFoods.get(mealType).size() - 1));
			} else {
				newFood = allFoods.get(mealType).get(0);
			}
					try {
						if(diesease!= null && diesease.equalsIgnoreCase(Constants.DIABETES)) {
							if(foods != null && foods.size() == 2 && (numarApel == 3 || numarApel%12 == 3)) {
								newFood = getFoodByName((String)jessRecomandation.recomand(diesease,null , this.getPreferencedFoods().get(mealType), foods));
								if(newFood != null || newFood.getName() != null) {
									if(jessRecomandation.validFood(foods, null))
										found = true;
									else 
										found = false;
								} else {
									found = false;
								}
								System.out.println("\n recomanded food = "+newFood.getName());
							} else {
								found = (Boolean)jessRecomandation.checkIfFoodItemIsDiabetic(newFood, foods);
							}
						} else {
									found = jessRecomandation.validFood(foods, newFood);
						}
				} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
						if (found){
							numarApel ++;
							break;
						}
		} 
		long endTime = System.currentTimeMillis();
		long difference = endTime - startTime;
		System.out.println(difference);
		System.out.println(new Date(difference));
		return this.copyFood(newFood);
	}
	
	public Food getRandomFoodCopyWithXmlConstraint(List<Food> foods,
			List<Food> allFoodsPerMeal, String mealType) {
		nr = 0;
		Food newFood = null;
		boolean found;
		System.out.println("###################### " + numarApel
				+ "  #######################");
		long startTime = System.currentTimeMillis();

		do {
			found = false;
			nr++;
			if (allFoods.get(mealType).size() > 1) {
				newFood = allFoods.get(mealType).get(this.randomGenerator.nextInt(allFoods.get(mealType).size() - 1));
			} else {
				newFood = allFoods.get(mealType).get(0);
			}
			try {
				for (Food food : foods) {
					if (this.exceptedFoods.containsKey(food.getName())
							&& this.exceptedFoods.get(food.getName()).contains(
									newFood.getName())) {
						found = true;
						break;
					}
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (found) {
				numarApel++;
			}
		} while (found);

		long endTime = System.currentTimeMillis();
		long difference = endTime - startTime;
		System.out.println(difference);
		System.out.println(new Date(difference));
		return this.copyFood(newFood);
	}
	
	private boolean checkIfIsDifferentFoods(List<Food> foods) {
		boolean isDifferent = true ;
		for(int i=0;i<foods.size(); i++){
			for(int j=i;j<foods.size();j++) {
				if(foods.get(i).getName().equalsIgnoreCase(foods.get(j).getName())) {
					isDifferent = false;
					break;
				}
			}
		}
		return isDifferent;
	}

	public List<Food> getNewSubstractFoodItem(List<Food> position1Foods, List<Food> position2Foods, String mealType, boolean getFromPreference) {
		List<Food> foods = new ArrayList<Food>();
		boolean found ;
//		if (!"lunch".equals(mealType)){
			for(Food food1 : position1Foods) {
				found = false;
				for(Food food2 : position2Foods) {
					if(food1.getName().equalsIgnoreCase(food2.getName())) {
						found = true;
						Food newFoodItem = new Food();
						if (food1.getPortions() == food2.getPortions()){
							newFoodItem = this.getRandomFoodCopy(foods, getFromPreference ? this.preferencedFoods.get(mealType) : this.allFoods.get(mealType),mealType);
//							newFoodItem.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD - 1) + 1);
						} else {
							newFoodItem = this.copyFood(food1);
							newFoodItem.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD - 1) + 1);
						}
						foods.add(newFoodItem);
						break;
					}
				}
				if (!found){
					foods.add(this.copyFood(food1));
				}
			}
//		} else { // first position is soup, then lunch, then meal
//			if (position1Foods.get(0).getName().equals(position2Foods.get(0).getName())){
//				foods.add(this.getFoodForLunch(position1Foods.get(0), position2Foods.get(0), "soup", getFromPreference));
//				foods.add(this.getFoodForLunch(position1Foods.get(0), position2Foods.get(0), "lunch", getFromPreference));
//				foods.add(this.getFoodForLunch(position1Foods.get(0), position2Foods.get(0), "meal", getFromPreference));
//			}
//		}
		
		return foods;
	}
	
	protected Food getFoodForLunch(Food food1, Food food2, String mealType, boolean getFromPreference){
		Food newFoodItem = new Food();
		if (food1.getPortions() == food2.getPortions()){
			newFoodItem = this.getRandomFoodCopy(null, getFromPreference? this.preferencedFoods.get(mealType) : this.allFoods.get(mealType),mealType);
		} else {
			newFoodItem = this.copyFood(food1);
			newFoodItem.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD - 1) + 1);
		}
		return newFoodItem;
	}
	
	public List<Food> getNewAdditionFoodItem(List<Food> position1Foods, List<Food> position2Foods , double particle1ProbabilityDir, double particle2ProbabilityDir) {
		
		List<Food> foods = new ArrayList<Food>();
		boolean foodFound; 
		for( Food food1 : position1Foods) {
			foodFound = false;
			for(Food food2 : position2Foods) {
				if(food1.getName().equalsIgnoreCase(food2.getName())) {
					foodFound = true;
					Food newFoodItem;
					if (food1.getPortions() == Constants.MUTATION || food2.getPortions() == Constants.MUTATION){
						newFoodItem = this.copyFood(food1);
						newFoodItem.setPortions(Constants.MUTATION);
					} else {
						newFoodItem = this.copyFood(food1);
						newFoodItem.setPortions((int) ((food1.getPortions()* particle1ProbabilityDir + food2.getPortions() * particle2ProbabilityDir)/(particle1ProbabilityDir + particle2ProbabilityDir)));
					}
					foods.add(newFoodItem);
					break;
				}
			}
			if (!foodFound){
				foods.add(this.copyFood(food1));
			}
		}	
	return foods;
	}
	
	public List<Food> getNewAdditionVelocityToPosition(List<Food> positionFoods, List<Food> velocityFoods, String mealType, boolean getFromPreferences) {
		
		List<Food> foods = new ArrayList<Food>();
		if(getFromPreferences){ //set 3 foods from preference and the last one from allFoods
			foods.add(this.getRandomFoodCopy(foods, this.preferencedFoods.get(mealType),mealType));
			foods.add(this.getRandomFoodCopy(foods, this.preferencedFoods.get(mealType),mealType));
			foods.add(this.getRandomFoodCopy(foods, this.preferencedFoods.get(mealType),mealType));
			
		} else { // get values from allFoods
			for ( int index = 0 ; index < velocityFoods.size(); index ++){
				Food newFoodItem;
				if (velocityFoods.get(index).getPortions() == Constants.MUTATION){
					newFoodItem = this.getRandomFoodCopy(foods, this.allFoods.get(mealType),mealType); // generate new food from allFoods list
				} else {
					newFoodItem = this.copyFood(positionFoods.get(index));	
				}
				foods.add(newFoodItem);
				
			}
		}
		return foods;
	}
	
	/**
	 * returns the gain in weight mesured in kg per week !!!!
	 * */
	public double gainWeight(double regularDailyCalories, double nrOfCaloriesNeeded) {
		gainedWeightPerWeek =(nrOfCaloriesNeeded - regularDailyCalories)/500 / 2.204;;
		return gainedWeightPerWeek;
	}
	
	// TODO actualSBP si actualKg sunt luate din log si sunt valorile reale angajatului care nu sunt corecte 
		// din moment ce logul ajuns pana acuma este nesanatos 
	public Map<String ,Double> preprocessing(RiskFactor riskFactor)
				throws ParserConfigurationException, SAXException, IOException, DOMException, ParseException {

		double newWeight = 0.0;
		double oldWeight = riskFactor.getWeight();
		double newSbp = 120;
		double oldSbp = riskFactor.getSbp();
		int age = riskFactor.getAdditional().getAge();
		diesease =riskFactor.isDiabetes() == true ? Constants.DIABETES : "no_diesease";
		
		RiskCalculation riskCalculation = new RiskCalculation();
		if (riskCalculation.riskCalculation(riskFactor) < 20){
			difference.put("weight", 0.0);
			difference.put("sbp", 0.0);
			difference.put("weeks", Constants.DEFAULT_DURATION_PSO);
			difference.put("weightInLastWeek", 0.0);
		} else {
			newWeight = 21 * riskFactor.getHeight()* riskFactor.getHeight();
			riskFactor.setWeight(newWeight);
			//calculate the sbp normal value for age = riskfactor.getAge()
			newSbp += (age - 25) / 5 + 1;
			newSbp += age > 40 ? ((age - 40) / 5 + 1) * 2 : 0;
			newSbp += age > 60 ? ((age - 60) / 5 + 1) * 3 : 0;
			riskFactor.setSbp(newSbp);
			if (riskCalculation.riskCalculation(riskFactor) > 19){
				do {
					riskFactor.setSbp(--newSbp);
					riskFactor.setWeight(--newWeight);
				} while (riskCalculation.riskCalculation(riskFactor) > 18);
			}
			double weightDifference = newWeight - oldWeight;
			
			System.out.println("New weight : " + newWeight);
			System.out.println("Initial weight" + oldWeight);
			
			if (weightDifference < 0 ){
				difference.put("weight", weightDifference < Constants.MAXIM_WEIGHT_LOST_PER_MOUNTH ? 
						Constants.MAXIM_WEIGHT_LOST_PER_MOUNTH : weightDifference);
				difference.put("sbp", newSbp - oldSbp);
				difference.put("newSbp",  newSbp);
				System.out.println("\n gainedPerWeek ===" + gainedWeightPerWeek);
				difference.put("oldSbp", oldSbp);
				difference.put("weeks",  Double.valueOf((int) (weightDifference + 1) / Constants.MAXIM_WEIGHT_LOST_PER_MOUNTH + 1));
				difference.put("weightInLastWeek", weightDifference - (difference.get("weeks") - 1) * difference.get("weight"));
			} else {
				difference.put("weight", weightDifference > Constants.MAXIM_WEIGHT_GAIN_PER_MOUNTH ? 
						Constants.MAXIM_WEIGHT_GAIN_PER_MOUNTH : weightDifference);
				difference.put("newSbp", newSbp);
				difference.put("oldSbp", oldSbp);
				difference.put("sbp", newSbp - oldSbp);
				difference.put("weeks",  Double.valueOf((int) (weightDifference + 1) / Constants.MAXIM_WEIGHT_GAIN_PER_MOUNTH + 1));
				difference.put("weightInLastWeek", weightDifference - (difference.get("weeks") - 1) * difference.get("weight"));
			}
		}
		riskFactor.setSbp(oldSbp);
		riskFactor.setWeight(oldWeight);
		return difference;
	}
	
	public double findKaloryNumber(double newWeight, int weeks, double kaloriesPerDay){
		return 500 * newWeight / 2.204 / weeks  + kaloriesPerDay;
	}
	
	public void initializeDocumentBuilder(String path){
		File fXmlFile = new File(path);
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder;
		try {
			dBuilder = dbFactory.newDocumentBuilder();
			this.doc = dBuilder.parse(fXmlFile);
			this.doc.getDocumentElement().normalize();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public List<Activity> getPreferencedActivitiesFromPath(Map<String, Activity> activityMap) throws ParserConfigurationException, SAXException, IOException{
		List<Activity> activities = new ArrayList<Activity>();
		
		Element personalPreference = (Element)doc.getElementsByTagName("preferences").item(0);
		Element personalActivity = (Element) personalPreference.getChildNodes().item(3);
		for (int index = 1 ; index < personalActivity.getChildNodes().getLength(); index  += 2){
			Element activityName = (Element) personalActivity.getChildNodes().item(index);
			activities.add(activityMap.get(activityName.getTextContent()));
		}
		
		Object[] activityKeys = activityMap.keySet().toArray();
		String activitString;
		while (activities.size() < Constants.FOODS_NUMBER_PER_BREAKFAST){
			activitString = activityKeys[randomGenerator.nextInt(activityKeys.length - 1)].toString();
			if (!activities.contains(activityMap.get(activitString))){
				activities.add(activityMap.get(activitString));
			}
		}
		return activities;
	}
	

	public Map<String, List<Food>> getPreferencedFoodsFromPath(Map<String, List<Food>> foodMap) throws ParserConfigurationException, SAXException, IOException{
		Map<String, List<Food>> preferencedFoods = new HashMap<String, List<Food>>();
		preferencedFoods.put(Constants.BREAKFAST, new ArrayList<Food>());
		preferencedFoods.put(Constants.LUNCH, new ArrayList<Food>());
		preferencedFoods.put(Constants.DINNER, new ArrayList<Food>());
		preferencedFoods.put(Constants.SNACK, new ArrayList<Food>());
//		preferencedFoods.put("soup", new ArrayList<Food>());
//		preferencedFoods.put("meal", new ArrayList<Food>());
		
		Element personalPreference = (Element)doc.getElementsByTagName("preferences").item(0);
		Element personalActivity = (Element) personalPreference.getChildNodes().item(1);
		for (int index = 1 ; index < personalActivity.getChildNodes().getLength(); index  += 2){
			String foodName = ((Element) personalActivity.getChildNodes().item(index)).getTextContent();
			for (String key : foodMap.keySet()){
				for (Food food : foodMap.get(key)){
					if (foodName.equals(food.getName())){
						preferencedFoods.get(key).add(food);
					}
				}
			}
		}
		
		this.completeFoodList(preferencedFoods.get(Constants.BREAKFAST), foodMap.get(Constants.BREAKFAST));
		this.completeFoodList(preferencedFoods.get(Constants.LUNCH), foodMap.get(Constants.LUNCH));
		this.completeFoodList(preferencedFoods.get(Constants.DINNER), foodMap.get(Constants.DINNER));
		this.completeFoodList(preferencedFoods.get(Constants.SNACK), foodMap.get(Constants.SNACK));
//		this.completeFoodList(preferencedFoods.get("soup"), foodMap.get("soup"));
//		this.completeFoodList(preferencedFoods.get("meal"), foodMap.get("meal"));
		return preferencedFoods;
	}
	
	protected void completeFoodList(List<Food> preferencedFoods, List<Food> allfoods){
		List<Integer> indexList = utils.getIntegerList(allfoods.size(), allfoods.size());
		Food newFood;
		int index = -1;
		boolean found;
		while (preferencedFoods.size() < 1){
			index ++;
			found = false;
			newFood = allfoods.get(indexList.get(index));
			for (Food preference : preferencedFoods){
				if (preference.getName().equals(newFood.getName())){
					found = true;
				}
			}
			if (!found){
				preferencedFoods.add(newFood);
			}
		}
			
	}

	public Food copyFood(Food food){
		Food newFood = new Food();
		newFood.setPortions(food.getPortions());
		newFood.setName(food.getName());
		FoodCharacteristics newCharacteristics = new FoodCharacteristics();
		if (food.getCharacteristics() != null){
			newCharacteristics.setKalory(food.getCharacteristics().getKalory());
			newCharacteristics.setGramsPerPortion(food.getCharacteristics().getGramsPerPortion());
		}
		newFood.setCharacteristics(newCharacteristics);
		return newFood;
	}
	
	public List<Food> copyFoodList(List<Food> oldFoods){
		List<Food> newList = new ArrayList<Food>();
		for (Food food : oldFoods){
			newList.add(this.copyFood(food));
		}
		return newList;
	}
	
	public Alimentation copyAlimentation(Alimentation oldAlimentation){
		Alimentation newAlimentation = new Alimentation();
		newAlimentation.setBreakFast(this.copyFoodList(oldAlimentation.getBreakFast()));
		newAlimentation.setDinner(this.copyFoodList(oldAlimentation.getDinner()));
		newAlimentation.setLunch(this.copyFoodList(oldAlimentation.getLunch()));
		newAlimentation.setSnack(this.copyFoodList(oldAlimentation.getSnack()));
		return newAlimentation;
	}
	
	public Activity copyActivity(Activity oldActivity){
		Activity newActivity = new Activity();
		if(oldActivity != null) {
		newActivity.setKalories(oldActivity.getKalories());
		newActivity.setKg(oldActivity.getKg());
		newActivity.setMinutes(oldActivity.getMinutes());
		newActivity.setName(oldActivity.getName());
		}
		return newActivity;
	}
	
	public List<Activity> copyActivities(List<Activity> oldActivities){
		List<Activity> newActivities = new ArrayList<Activity>();
		for (Activity activity : oldActivities){
			newActivities.add(this.copyActivity(activity));
		}
		return newActivities;
	}
	
	public Map<String, Set<String>> getExceptedFoods() {
		return exceptedFoods;
	}

	public void setExceptedFoods(Map<String, Set<String>> exceptedFoods) {
		this.exceptedFoods = exceptedFoods;
	}

	public Map<String, List<Food>> getAllFoods() {
		return allFoods;
	}

	public void setAllFoods(Map<String, List<Food>> allFoods) {
		this.allFoods = allFoods;
	}
	
	public List<Activity> generateRandomActivities(double weight) {
		List<Activity> activitiesList = new ArrayList<Activity>();
		for (Integer index : utils.getIntegerList(
				Constants.ACTIVITY_NUMBER_PER_DAY, this.preferencedActivities.size())) {
			if(this.preferencedActivities.get(index) != null){
			Activity activity = this.copyActivity(this.preferencedActivities.get(index));
			activity.setKg(weight);
			activitiesList.add(activity);
			}
		}
		return activitiesList;
	}
	
	public Alimentation generateRandomAlimentation(String constraintMethod) {
		Alimentation alimentation = new Alimentation();

		alimentation.setBreakFast(generateRandomFoodPerMeal(
				Constants.FOODS_NUMBER_PER_BREAKFAST, Constants.BREAKFAST,
				constraintMethod));
		alimentation.setDinner(generateRandomFoodPerMeal(
				Constants.FOODS_NUMBER_PER_BREAKFAST, Constants.DINNER,
				constraintMethod));
		alimentation.setLunch(generateRandomFoodPerMeal(
				Constants.FOODS_NUMBER_PER_BREAKFAST, Constants.LUNCH,
				constraintMethod));
		alimentation.setSnack(generateRandomFoodPerMeal(
				Constants.FOODS_NUMBER_PER_BREAKFAST, Constants.SNACK,
				constraintMethod));
		return alimentation;
	}
	public List<Food> generateRandomFoodPerMeal(int size, String mealType,
			String constraintMethod) {
		List<Food> foods = new ArrayList<Food>();
		// if ("lunch".equals(mealType)){ //generate one food from soup, lunch
		// and meal type.
		// Food lunchFood1 =
		// this.copyFood(this.allFoods.get("soup").get(randomGenerator.nextInt(this.allFoods.get("soup").size()-1)));
		// lunchFood1.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD
		// - 1) + 1);
		// Food lunchFood2 =
		// this.copyFood(this.allFoods.get("lunch").get(randomGenerator.nextInt(this.allFoods.get("lunch").size()-1)));
		// lunchFood2.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD
		// - 1) + 1);
		// Food lunchFood3 =
		// this.copyFood(this.allFoods.get("meal").get(randomGenerator.nextInt(this.allFoods.get("meal").size()-1)));
		// lunchFood3.setPortions(randomGenerator.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD
		// - 1) + 1);
		// foods.add(lunchFood1);
		// foods.add(lunchFood2);
		// foods.add(lunchFood3);
		// } else {
		for (Integer index : utils.getIntegerList(size, allFoods.get(mealType)
				.size())) {
			Food newFood;
			if (Constants.XML_CONSTRAINT_MENTHOD.equals(constraintMethod)) {
				newFood = this.getRandomFoodCopyWithXmlConstraint(foods,
						this.allFoods.get(mealType), mealType);
			} else {
				newFood = this.getRandomFoodCopy(foods,
						this.allFoods.get(mealType), mealType);
			}
			newFood.setPortions(randomGenerator
					.nextInt(Constants.MAXIM_NUMBER_PORTION_PER_FOOD - 1) + 1);
			foods.add(newFood);
		}
		// }
		return foods;
	}

	public double getDesireKalory() {
		return desireKalory;
	}

	public void setDesireKalory(double desireKalory) {
		this.desireKalory = desireKalory;
	}

	public double getDesireSbp() {
		return desireSbp;
	}

	public void setDesireSbp(double desireSbp) {
		this.desireSbp = desireSbp;
	}
	
	public double fitness(double allCalories, double paretoOptimalMethod, double sbp)
			throws DOMException, ParserConfigurationException, SAXException,
			IOException, ParseException {

		double fitnessValue = 0;
		if (allCalories > 0 && paretoOptimalMethod == 1) {
			// aggreagation method
			fitnessValue = allCalories * lambda[0]
					+ fitnessSbp(allCalories, sbp) * lambda[1];
		} else if (allCalories > 0 && paretoOptimalMethod == 2) {
			// weighted metrics method
//			int p = Constants.EUCLIDIAN_METRICS;
			// define goal or refference point to attain
			// referinta cartea Talbi - Metaeuristics pag 327
			double fitnessCaloriesGoal = this.getDesireKalory();
			double fitnessSbpGoal = this.getDesireSbp();
			fitnessValue = Math.sqrt(Math.min(
					lambda[0] * Math.pow(Math.abs(allCalories - fitnessCaloriesGoal), 2),
					lambda[1] * Math.pow(Math.abs(fitnessSbp(allCalories, sbp) - fitnessSbpGoal), 2)));
		} else {
			fitnessValue = Constants.MAX_DOUBLE;
		}
		return fitnessValue;
	}

	// relatia intre greutate si sbp este ca la fiecare kg scazut din greutate
	// se scade si 1 mmHg din sbp
	public double fitnessSbp(double allCalories, double sbp) throws DOMException, ParserConfigurationException, SAXException, IOException, ParseException {
		double gainedWieght = this.gainWeight(allCalories, this.getDesireKalory()); 
		return sbp - gainedWieght;
	}

	public Food getFoodByName(String name){
		Food findedFood = new Food();
		for(Food food : this.allFoods.get(Constants.BREAKFAST)) {
			if(food.getName().equalsIgnoreCase(name)) {
				findedFood = food;
				break;
			}
		}
		for(Food food : this.allFoods.get(Constants.LUNCH)) {
			if(food.getName().equalsIgnoreCase(name)) {
				findedFood = food;
				break;
			}
		}
		for(Food food : this.allFoods.get(Constants.DINNER)) {
			if(food.getName().equalsIgnoreCase(name)) {
				findedFood = food;
				break;
			}
		}
		for(Food food : this.allFoods.get(Constants.SNACK)) {
			if(food.getName().equalsIgnoreCase(name)) {
				findedFood = food;
				break;
			}
		}
		return findedFood;
	}
	
	private List<Food> setAllFoods() {
		List<Food> allFoods = new ArrayList<Food>();
		allFoods.addAll(this.allFoods.get(Constants.BREAKFAST));
		allFoods.addAll(this.allFoods.get(Constants.DINNER));
		allFoods.addAll(this.allFoods.get(Constants.SNACK));
		allFoods.addAll(this.allFoods.get(Constants.LUNCH));

		return allFoods;
	}
	

	
}

		